﻿using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.ComponentModel;

namespace Ids4.Api.Models
{

    /// <summary>
    /// ResultCode
    /// </summary>
    public enum ResultCode
    {
        #region 100
        /// <summary>
        /// 操作失败
        /// </summary>
        [Description("操作失败")]
        FAIL = 100,
        /// <summary>
        /// 参数错误
        /// </summary>
        [Description("参数错误")]
        PARAM_ERROR = 101,
        /// <summary>
        /// 验证码错误
        /// </summary>
        [Description("验证码错误")]
        CAPTCHA_ERROR = 102,
        /// <summary>
        /// 登录错误
        /// </summary>
        [Description("登录错误")]
        LOGIN_ERROR = 103,
        /// <summary>
        /// 自定义异常
        /// </summary>
        [Description("自定义异常")]
        CUSTOM_ERROR = 104,
        /// <summary>
        /// 非法请求
        /// </summary>
        [Description("非法请求")]
        INVAARWD_REQUEST = 105,
        #endregion

        #region 200
        /// <summary>
        /// 请求成功
        /// </summary>
        [Description("请求成功")]
        SUCCESS = 200,
        #endregion

        #region 300
        /// <summary>
        /// 多种选择
        /// </summary>
        [Description("多种选择")]
        MULTIPLE_CHOICE = 300,
        /// <summary>
        /// 永久移动
        /// </summary>
        [Description("永久移动")]
        MOVED_PERMANENTLY = 301,
        /// <summary>
        /// 临时移动
        /// </summary>
        [Description("临时移动")]
        FOUND = 302,
        /// <summary>
        /// 未找到
        /// </summary>
        [Description("未找到")]
        SEE_OTHER = 303,
        #endregion

        #region 400
        /// <summary>
        /// BadRequest
        /// </summary>
        [Description("BadRequest")]
        BAD_REQUEST = 400,
        /// <summary>
        /// 未认证
        /// </summary>
        [Description("未认证")]
        DENY = 401,
        /// <summary>
        /// 未授权
        /// </summary>
        [Description("未授权")]
        FORBIDDEN = 403,
        /// <summary>
        /// 未找到
        /// </summary>
        [Description("未找到")]
        NOT_FOUND = 404,
        /// <summary>
        /// 不允许使用该方法
        /// </summary>
        [Description("不允许使用该方法")]
        METHOD_NOT_ALLOWED = 405,
        #endregion

        #region 500
        /// <summary>
        /// 服务端出错啦
        /// </summary>
        [Description("服务端出错啦")]
        GLOBAL_ERROR = 500,
        /// <summary>
        /// 尚未实施
        /// </summary>
        [Description("尚未实施")]
        NOT_IMPL = 501,
        /// <summary>
        /// 错误网关
        /// </summary>
        [Description("错误网关")]
        GATEWAY_ERROR = 502,
        /// <summary>
        /// 服务不可用
        /// </summary>
        [Description("服务不可用")]
        SERVICE_UNAVAILAVLE = 503,
        /// <summary>
        /// 网关超时
        /// </summary>
        [Description("网关超时")]
        GATEWAY_TIMEOUT = 504,
        /// <summary>
        /// 服务端出错啦
        /// </summary>
        [Description("HTTP 版本不受支持")]
        HTTPVERSION_ERROR = 505,
        #endregion
    }

    public class ApiResult
    {
        public int Code { get; set; }
        public string Msg { get; set; }
        /// <summary>
        /// 如果data值为null，则忽略序列化将不会返回data字段
        /// </summary>
        [JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
        public object Data { get; set; }

        /// <summary>
        /// 初始化一个新创建的APIResult对象，使其表示一个空消息
        /// </summary>
        public ApiResult()
        {
        }

        /// <summary>
        /// 初始化一个新创建的 ApiResult 对象
        /// </summary>
        /// <param name="code"></param>
        /// <param name="msg"></param>
        public ApiResult(int code, string msg)
        {
            Code = code;
            Msg = msg;
        }

        /// <summary>
        /// 初始化一个新创建的 ApiResult 对象
        /// </summary>
        /// <param name="code"></param>
        /// <param name="msg"></param>
        public ApiResult(int code, string msg, object data)
        {
            Code = code;
            Msg = msg;
            if (data != null)
            {
                Data = data;
            }
        }

        /// <summary>
        /// 返回成功消息
        /// </summary>
        /// <returns></returns>
        public ApiResult Success()
        {
            Code = (int)ResultCode.SUCCESS;
            Msg = "success";
            return this;
        }

        /// <summary>
        /// 返回成功消息
        /// </summary>
        /// <param name="data">数据对象</param>
        /// <returns>成功消息</returns>
        public static ApiResult Success(object data) { return new ApiResult((int)ResultCode.SUCCESS, "success", data); }

        /// <summary>
        /// 返回成功消息
        /// </summary>
        /// <param name="msg">返回内容</param>
        /// <returns>成功消息</returns>
        public static ApiResult Success(string msg) { return new ApiResult((int)ResultCode.SUCCESS, msg, null); }

        /// <summary>
        /// 返回成功消息
        /// </summary>
        /// <param name="msg">返回内容</param>
        /// <param name="data">数据对象</param>
        /// <returns>成功消息</returns>
        public static ApiResult Success(string msg, object data) { return new ApiResult((int)ResultCode.SUCCESS, msg, data); }

        /// <summary>
        /// 访问被拒
        /// </summary>
        /// <param name="apiResult"></param>
        /// <returns></returns>
        public ApiResult On401()
        {
            Code = (int)ResultCode.DENY;
            Msg = "access denyed";
            return this;
        }
        public ApiResult Error(ResultCode resultCode, string msg = "")
        {
            Code = (int)resultCode;
            Msg = msg;
            return this;
        }

        /// <summary>
        /// 返回失败消息
        /// </summary>
        /// <param name="code"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static ApiResult Error(int code, string msg) { return new ApiResult(code, msg); }

        /// <summary>
        /// 返回失败消息
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static ApiResult Error(string msg) { return new ApiResult((int)ResultCode.CUSTOM_ERROR, msg); }

        public override string ToString()
        {
            return $"msg={Msg},data={Data}";
        }
    }

    public class ApiResult<T> : ApiResult
    {
        public T Result { get; set; }
    }
}
